﻿using System.Collections;
using System.Diagnostics;
using System.Diagnostics.Eventing.Reader;
using ModuleBase;
using ModuleBase.googoltech.GTS;
using Newtonsoft.Json;
using Prism.Ioc;

namespace TrackModule
{
    public class TrackModule : ModuleBase.ModuleBase
    {
        private IAxisCardService _axisCardService;
        private ModuleStateService _moduleStateService;
        private IContainerProvider containerProvider;
        bool outputs = false;
        bool isFinished = false;

        private object _parameter1;
        public object Parameter1
        {
            get => _parameter1;
            set
            {
                if (_parameter1 != value)
                {
                    _parameter1 = value;
                    OnPropertyChanged(nameof(Parameter1));
                }
            }
        }

        private double _parameter2;
        public double Parameter2
        {
            get => _parameter2;
            set
            {
                if (_parameter2 != value)
                {
                    _parameter2 = value;
                    OnPropertyChanged(nameof(Parameter2));
                }
            }
        }

        private string _parameter3;
        public string Parameter3
        {
            get => _parameter3;
            set
            {
                if (_parameter3 != value)
                {
                    _parameter3 = value;
                    OnPropertyChanged(nameof(Parameter3));
                }
            }
        }

        private double _parameter4;
        public double Parameter4
        {
            get => _parameter4;
            set
            {
                if (_parameter4 != value)
                {
                    _parameter4 = value;
                    OnPropertyChanged(nameof(Parameter4));
                }
            }
        }
        public override Dictionary<string, object> GetProperties()
        {
            return new Dictionary<string, object>
            {
                { "轴号", Parameter1 },
                { "速度", Parameter2 },
            };
        }

        public override Dictionary<string, List<object>> PropertyOptions { get; } = new Dictionary<string, List<object>>
        {
            { "方向", new List<object> { "正向", "负向" } },
            { "轴号", new List<object>{ 1,2,3,4,5,6,7,8 } }
        };

        public TrackModule(IAxisCardService axisCardService, ModuleStateService moduleStateService)
        {
            Name = "轨道流程";
        }

        public override bool Execute()
        {
            CancellationTokenSource source1 = new CancellationTokenSource();
            Status = ModuleStatus.Executing; // 设置状态为执行中
            AxisParm _axisX = GetAxisByNumber((int)Parameter2);
            var placement = 0.0; //放版位
            var boardposition = 0.0;
            using var mdb = containerProvider.Resolve<MDbContext>();
            var _mParam = mdb.MParams.FirstOrDefault(x => x.Name == "Placement");
            if (_mParam != null)
            {
                var _point = JsonConvert.DeserializeObject<MPoint>(_mParam.Value);
                placement = _point.X;
            }
            _mParam = mdb.MParams.FirstOrDefault(x => x.Name == "Boardposition");
            if (_mParam != null)
            {
                var _point = JsonConvert.DeserializeObject<MPoint>(_mParam.Value);
                boardposition = _point.X;
            }
            try
            {
                int stepNum = 1;
                while (true)
                {
                    var diport = GTSCard.GetDiPort1((short)_axisX.CardNo);
                    var bitArray = new BitArray(new[] { diport });
                    /*
                     EXI 4 轨道流入光电
                     EXI 5 轨道到位光电
                     EXI 6 轨道流出光电
                     */
                    switch (stepNum)
                    {
                        case 0: //等进板信号
                            stepNum = 1;
                            break;
                        case 1: //判断轨道是否有板
                            if (!bitArray[5])
                            {
                                stepNum = 2;
                            }
                            break;
                        case 2: //轨道进板
                            if (bitArray[4])
                            {
                                var curPos = GTSCard.GetPos(_axisX);
                                double _tarPos = curPos + 0.1;
                                CancellationToken token = source1.Token;
                                Task.Run(() => GoAction(token, _axisX, _tarPos, Parameter2), token);
                            }
                            else
                            {
                                source1.Cancel();
                                GTSCard.AxisStop(_axisX, 0);
                                stepNum = 21;
                            }
                            break;
                        case 21: //感应到位光电，气缸上抬
                            if (bitArray[5])
                            {
                                GTSCard.SetDo((short)_axisX.CardNo, (short)10, 1);
                                GTSCard.SetDo((short)_axisX.CardNo, (short)13, 1);

                                //给工作流一个到位信号，允许工作，进入等待出板流程

                                stepNum = 3;
                            }
                            break;
                        case 3: // 轨道出板
                            if (isFinished) //读到完成信号，开始出板
                            {
                                GTSCard.SetDo((short)_axisX.CardNo, (short)10, 0);
                                GTSCard.SetDo((short)_axisX.CardNo, (short)13, 0);

                                stepNum = 31;
                            }
                            break;
                        case 31:
                            if (bitArray[6])
                            {
                                var curPos = GTSCard.GetPos(_axisX);
                                double _tarPos = curPos - 0.1;
                                CancellationToken token = source1.Token;
                                Task.Run(() => GoAction(token, _axisX, _tarPos, Parameter2), token);
                            }
                            else
                            {
                                source1.Cancel();
                                GTSCard.AxisStop(_axisX, 0);
                                stepNum = 0;
                            }
                            break;
                    }
                }
            }
            catch (Exception exp)
            {
                outputs = false;
            }
            return outputs;
        }

        public override async Task<bool> ExecuteAsync()
        {
            var result = await Task.Run(() => Execute());
            return result;
        }
        public override void Initialize()
        {

        }
        private AxisParm GetAxisByNumber(int axisNumber)
        {
            switch (axisNumber)
            {
                case 1: return _axisCardService.A1;
                case 2: return _axisCardService.A2;
                case 3: return _axisCardService.A3;
                case 4: return _axisCardService.A4;
                case 5: return _axisCardService.A5;
                case 6: return _axisCardService.A6;
                case 7: return _axisCardService.A7;
                case 8: return _axisCardService.A8;
                default: return _axisCardService.A1;
            }
        }
        private void GoAction(CancellationToken token, AxisParm axisN, double tartgetN, double speed)
        {
            try
            {
                int stepnum = 0;
                Stopwatch sw = Stopwatch.StartNew();
                while (true)
                {
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    switch (stepnum)
                    {
                        case 0:
                            {
                                GTSCard.AxisPosMove(ref axisN, tartgetN, speed);
                                stepnum = 1;
                            }
                            break;
                        case 1:
                            if (GTSCard.AxisPosMoveCheckDone(axisN))
                            {
                                stepnum = 2;
                            }
                            break;
                        case 2:
                            if (sw.Elapsed.TotalSeconds > 0.5)
                            {
                                sw.Stop();
                                return;
                            }
                            break;
                        default:
                            break;
                    }
                    System.Threading.Thread.Sleep(100);
                }
            }
            catch (Exception ex)
            {
            }
        }
    }
}
